package com.lf.emv;



import java.util.Arrays;

public class api {
    //BIN表内型设置参数
    public static final char BIN_A_LIST = 0x00;
    public static final char BIN_B_LIST = 0X01;
    public static final char BIN_BLK_LIST = 0x02;

    // 联机返回值
    public static final char ONLINE_APPROVE = 0x00;        // 后台批准交易
    public static final char ONLINE_REFER = 0x02;        // 后台要求参考
    public static final char ONLINE_DENIAL = 0x03;        // 后台拒绝交易
    public static final char ONLINE_TIMEOUT = 0x04;        // 连接后台超时
    public static final char ONLINE_OTHER_ERROR = 0x05;        // 从后台接收到错误数据，校验错等

    //  返回值定义
    public static final int EMV_RET_ERROR_OK = 0;       // 批准交易或者操作成功
    public static final int EMV_RET_ERROR_PARA = -1;      // 参数错误
    public static final int EMV_RET_ERROR_CHECKSUM = -2;      // 校验和错
    public static final int EMV_RET_ERROR_DATA = -3;      // 错误的数据
    public static final int EMV_RET_ERROR_ICCARD = -4;      //与IC 通信失败
    public static final int EMV_RET_ERROR_SW = -5;      // IC卡返回错误状态值
    public static final int EMV_RET_ERROR_CARD_BLOCKED = -6;      // IC卡被锁定
    public static final int EMV_RET_ERROR_APP_BLOCKED = -7;      // 卡内应用被锁定
    public static final int EMV_RET_ERROR_OVERFLOW = -8;      // 内存溢出
    public static final int EMV_RET_ERROR_NO_APP = -9;      // 卡内无该文件
    public static final int EMV_RET_ERROR_NOT_ACCEPTED = -10;     // 应用不被接受
    public static final int EMV_RET_ERROR_USER_CANCEL = -11;     // 操作员取消交易
    public static final int EMV_RET_ERROR_NO_LOG = -12;     // 卡内无记录
    public static final int EMV_RET_ERROR_DATA_MISSING = -13;     // 必要数据缺失
    public static final int EMV_RET_ERROR_EXPIRED = -14;     // 公钥过期或者应用过期
    public static final int EMV_RET_ERROR_BYPASSPIN = -15;         // 取消PIN输入
    public static final int EMV_RET_ERROR_FORCE_ACCEPT = -16;         // 操作者强制批准交易
    public static final int EMV_RET_ERROR_PIN_BLOCKED = -17;     // pin验证被锁定
    public static final int EMV_RET_ERROR_DECLINE = -18;     // IC卡拒绝交易
    public static final int EMV_RET_ERROR_TERMINATE = -19;     // 终止交易
    public static final int EMV_RET_ERROR_AMTEXCEED = -21;         //超额
    public static final int EMV_RET_ERROR_NEXTAPP = -22;         //选择下一个应用
    public static final int EMV_RET_ERROR_PHONETRY = -23;         //手机重新放一次
    public static final int EMV_RET_ERROR_EXPIREONLINE = -24;         //过期需要联机
    public static final int EMV_RET_ERROR_RETEMV = -25;         //去执行借贷记操作

    public static final int EMV_RET_ERROR_SDSES = -30;         //神思员工卡
    
    
    public static final int KERNEL_TEST_EMV = 0;
    public static final int KERNEL_TEST_PBOC = 1;
    public static final int KERNEL_TEST_UICS = 2;
	private static api instance;
    public static api getInstance()
    {
       if (instance == null) {
    	   instance = new api();
      }
      return instance;
    }
    //  常用结构定义
    public class EMV_TERM_FIX_DATA              // 终端固有数据元结构
    {
        public EMV_TERM_FIX_DATA()
        {
            TermID= new char[8];
            MerchantID = new char[15];
            MerchCatCode= new char[2];
            MCHLOCLen = 0;
            MCHNameLoc= new char[256];
            TermCntrCode= new char[2];
            TransCurCode= new char[2];
            ReferCurCode= new char[2];
            TransCurExp = 0;
            ReferCurExp = 0;
            ReferCurrCon = 0;
            tRFU = new char[2];
        }
        public void clear()
        {
            Arrays.fill(TermID, (char) 0x00);
            Arrays.fill(MerchantID, (char) 0x00);
            Arrays.fill(MerchCatCode, (char) 0x00);
            MCHLOCLen = 0;
            Arrays.fill(MCHNameLoc, (char) 0x00);
            Arrays.fill(TermCntrCode, (char) 0x00);
            Arrays.fill(TransCurCode, (char) 0x00);
            Arrays.fill(ReferCurCode, (char) 0x00);
            TransCurExp = 0;
            ReferCurExp = 0;
            ReferCurrCon = 0;
        }
        public int sizeof()
        {
            int len = 0;
            len += TermID.length;
            len += MerchantID.length;
            len += MerchCatCode.length;
            len += 3;
            len += MCHNameLoc.length;
            len += TermCntrCode.length;
            len += TransCurCode.length;
            len += ReferCurCode.length;
            len += 4;
            len += tRFU.length;
            return len;
        }
        public char[] getChar()
        {
            char[] retchar = new char[this.sizeof()];
            int offset = 0;
            System.arraycopy(TermID, 0, retchar, offset, TermID.length);
            offset += TermID.length;
            System.arraycopy(MerchantID, 0, retchar, offset, MerchantID.length);
            offset += MerchantID.length;
            System.arraycopy(MerchCatCode, 0, retchar, offset, MerchCatCode.length);
            offset += MerchCatCode.length;
            retchar[offset ++] = RFU;
            retchar[offset ++] = (char) (MCHLOCLen >> 16);
            retchar[offset ++] = (char) (MCHLOCLen & 0xffff);
            System.arraycopy(MCHNameLoc, 0, retchar, offset, MCHNameLoc.length);
            offset += MCHNameLoc.length;
            System.arraycopy(TermCntrCode, 0, retchar, offset, TermCntrCode.length);
            offset += TermCntrCode.length;
            System.arraycopy(TransCurCode, 0, retchar, offset, TransCurCode.length);
            offset += TransCurCode.length;
            System.arraycopy(ReferCurCode, 0, retchar, offset, ReferCurCode.length);
            offset += ReferCurCode.length;
            retchar[offset ++] = TransCurExp;
            retchar[offset ++] = ReferCurExp;
            retchar[offset ++] = (char) (ReferCurrCon >> 16);
            retchar[offset ++] = (char) (ReferCurrCon & 0xffff);
            System.arraycopy(tRFU, 0, retchar, offset, tRFU.length);
            offset += tRFU.length;
            return retchar;
        }
        
        public void setChar(char[] buff, int offset)
        {
            System.arraycopy(buff, offset, TermID, 0, TermID.length);
            offset += TermID.length;
            System.arraycopy(buff, offset, MerchantID, 0, MerchantID.length);
            offset += MerchantID.length;
            System.arraycopy(buff, offset, MerchCatCode, 0, MerchCatCode.length);
            offset += MerchCatCode.length;
            RFU = buff[offset++];
            MCHLOCLen = buff[offset++] << 16;
            MCHLOCLen |= buff[offset++];
            System.arraycopy(buff, offset, MCHNameLoc, 0, MCHNameLoc.length);
            offset += MCHNameLoc.length;
            System.arraycopy(buff, offset, TermCntrCode, 0, TermCntrCode.length);
            offset += TermCntrCode.length;
            System.arraycopy(buff, offset, TransCurCode, 0, TransCurCode.length);
            offset += TransCurCode.length;
            System.arraycopy(buff, offset, ReferCurCode, 0, ReferCurCode.length);
            offset += ReferCurCode.length;
            TransCurExp = buff[offset++];
            ReferCurExp = buff[offset++];
            ReferCurrCon = buff[offset++] << 16;
            ReferCurrCon |= buff[offset++];
            System.arraycopy(buff, offset, tRFU, 0, tRFU.length);
            offset += tRFU.length;
        }
        
        public char[]   TermID;                //8  // Terminal identifier
        public char[]   MerchantID;        //15 // Merchant identifier
        public char[]   MerchCatCode;       //2  // Merchant category code
        public char   RFU;                // RFU
        public int  MCHLOCLen;              // the length of Merchant Name and Location
        public char[]   MCHNameLoc;    //256    // Merchant Name and Location
        public char[]   TermCntrCode;  //2      // Terminal country code
        public char[]   TransCurCode;  //2      // Transaction currency code
        public char[]   ReferCurCode;  //2      // Transaction Reference Currency Code
        public char   TransCurExp;            // Transation Currency Exponent
        public char   ReferCurExp;            // Transation Reference Currency Exponent
        public int  ReferCurrCon;           // Transaction Reference Currency Conversion
        public char[]   tRFU;          //2 byte
    }
    
    private native int EmvSetTerminalData(EMV_TERM_FIX_DATA[] pData);
    private native int EmvGetTerminalData(EMV_TERM_FIX_DATA[] pData);
    
    public int Emv_set_terminal_data(EMV_TERM_FIX_DATA[] pData)
    {
        return EmvSetTerminalData(pData);
    }
    public int Emv_get_terminal_data(EMV_TERM_FIX_DATA[] pData)
    {
        return EmvGetTerminalData(pData);
    }

    public class EMV_QPS_APP_DATA
    {
        public EMV_QPS_APP_DATA()
        {
            QPSLimit = 0;
            UnsignLimit = 0;
        }
        public void clear()
        {
            QPSLimit = 0;
            UnsignLimit = 0;
        }
        public int QPSLimit;
        public int UnsignLimit;
    }

    private native int EmvSetQpsAppdata(EMV_QPS_APP_DATA[] pData);
    private native int EmvGetQpsAppdata(EMV_QPS_APP_DATA[] pData);
    
    public int Emv_set_qps_app_data(EMV_QPS_APP_DATA[] pData)
    {
        return EmvSetQpsAppdata(pData);
    }
    public int Emv_get_qps_app_data(EMV_QPS_APP_DATA[] pData)
    {
        return EmvGetQpsAppdata(pData);
    }
    
    public class EMV_QPS_FUNC_DATA
    {
        public EMV_QPS_FUNC_DATA()
        {
            QPSFlag = 0;
            BINAFlag = 0;
            BINBFlag = 0;
            CdcvmFlag = 0;
            UnsignFlag = 0;
        }
        public void clear()
        {
            QPSFlag = 0;
            BINAFlag = 0;
            BINBFlag = 0;
            CdcvmFlag = 0;
            UnsignFlag = 0;
        }
        public char QPSFlag;
        public char BINAFlag;
        public char BINBFlag;
        public char CdcvmFlag;
        public char UnsignFlag;
    }

    private native int EmvSetQpsFuncData(EMV_QPS_FUNC_DATA[] pData);
    private native int EmvGetQpsFuncData(EMV_QPS_FUNC_DATA[] pData);
    
    public int Emv_set_qps_func_data(EMV_QPS_FUNC_DATA[] pData)
    {
        return EmvSetQpsFuncData(pData);
    }
    public int Emv_get_qps_func_data(EMV_QPS_FUNC_DATA[] pData)
    {
        return EmvGetQpsFuncData(pData);
    }
    
    private native int EmvSetOdaFuncData(boolean flag);
    private native boolean EmvGetOdaFuncData();

    public int Emv_set_oda_func_data(boolean flag)
    {
        return EmvSetOdaFuncData(flag);
    }
    
    public boolean Emv_get_oda_func_data()
    {
        return EmvGetOdaFuncData();
    }
    
    private native boolean EmvGetBincardOda();
    private native void EmvSetBincardOda(boolean flag);
    
    public boolean emv_Get_Bincard_Oda()
    {
        return EmvGetBincardOda();
    }
    public void emv_Set_Bincard_Oda(boolean flag)
    {
        EmvSetBincardOda(flag);
    }
    
    private native boolean EmvGetOdaAuto();
    private native void EmvSetOdaAuto(boolean flag);
    
    public boolean emv_get_oda_auto()
    {
        return EmvGetOdaAuto();
    }
    public void emv_set_oda_auto(boolean flag)
    {
        EmvSetOdaAuto(flag);
    }
    
    private native boolean EmvGetReadAppdataForce();
    private native void EmvSetReadAppdataForce(boolean flag);
    
    public boolean emv_get_read_appdata_force()
    {
        return EmvGetReadAppdataForce();
    }

    public void emv_set_read_appdata_force(boolean flag)
    {
        EmvSetReadAppdataForce(flag);
    }

    
    private native boolean EmvGetKernelMode();
    private native int EmvSetKernelMode(boolean flag);
    
    public int emv_set_kernel_mode(boolean flag)
    {
        return EmvSetKernelMode(flag);
    }
    public boolean emv_get_kernel_mode()
    {
        return EmvGetKernelMode();
    }

    public class EMV_APPLE_FUNC_DATA
    {
        public EMV_APPLE_FUNC_DATA()
        {
            AppleFlag = 0;
        }
        public void clear()
        {
            AppleFlag = 0;
        }
        public char AppleFlag;
    }

    private native int EmvSetAppleFuncData(EMV_APPLE_FUNC_DATA[] pData);
    private native int EmvGetAppleFuncData(EMV_APPLE_FUNC_DATA[] pData);
    
    public int Emv_set_apple_func_data(EMV_APPLE_FUNC_DATA[] pData)
    {
        return EmvSetAppleFuncData(pData);
    }
    public int Emv_get_apple_func_data(EMV_APPLE_FUNC_DATA[] pData)
    {
        return EmvGetAppleFuncData(pData);
    }
    
    /*
    *   返回值
    *   0:  表示借记
    *   1:  表示贷记
    *   -1: 表示获取失败
    */
    private native int EmvCreditAidJudge();
    
    public int Emv_credit_aid_judge()
    {
        return EmvCreditAidJudge();
    }
    
    public class EMV_APP_INIT_DATA
    {
        public EMV_APP_INIT_DATA()
        {
            TargetPer = 0;
            MaxTargetPer = 0;
            FloorLimit = 0;
            Threshold = 0;
            ECTransLimit = 0;
            QPBOCTransLimit = 0;
            QPBOCFloorLimit = 0;
            QPBOCCVMLimit = 0;
            TACDenial = new char[5];
            TACOnline = new char[5];
            TACDefault = new char[5];
            AcquierId = new char[6];
            LenOfdDOL = 0;
            dDOL = new char[252];
            LenOftDOL = 0;
            tDOL = new char[252];
            Version = new char[2];
            RiskManDataLen = 0;
            RiskManData = new char[8];
            tRFU = new char[2];
        }
        public void clear()
        {
            TargetPer = 0;
            MaxTargetPer = 0;
            FloorLimit = 0;
            Threshold = 0;
            ECTransLimit = 0;
            QPBOCTransLimit = 0;
            QPBOCFloorLimit = 0;
            QPBOCCVMLimit = 0;
            Arrays.fill(TACDenial, (char) 0x00);
            Arrays.fill(TACOnline, (char) 0x00);
            Arrays.fill(TACDefault, (char) 0x00);
            Arrays.fill(AcquierId, (char) 0x00);
            LenOfdDOL = 0;
            Arrays.fill(dDOL, (char) 0x00);
            LenOftDOL = 0;
            Arrays.fill(tDOL, (char) 0x00);
            Arrays.fill(Version, (char) 0x00);
            RiskManDataLen = 0;
            Arrays.fill(RiskManData, (char) 0x00);
        }
        
        public int sizeof()
        {
            int len = 8 * 2; //int型占用两个char的空间
            len += TACDenial.length;
            len += TACOnline.length;
            len += TACDefault.length;
            len += AcquierId.length;
            len += 2;
            len += dDOL.length;
            len += tDOL.length;
            len += Version.length;
            len += 1;
            len += RiskManData.length;
            len += tRFU.length;
            return len;
        }
        
        public char[] getChar()
        {
            char[] retchar = new char[this.sizeof()];
            int offset = 0;
            retchar[offset ++] = (char) (TargetPer >> 16);
            retchar[offset ++] = (char) (TargetPer & 0xffff);
            retchar[offset ++] = (char) (TargetPer >> 16);
            retchar[offset ++] = (char) (TargetPer & 0xffff);
            retchar[offset ++] = (char) (TargetPer >> 16);
            retchar[offset ++] = (char) (TargetPer & 0xffff);
            retchar[offset ++] = (char) (TargetPer >> 16);
            retchar[offset ++] = (char) (TargetPer & 0xffff);
            retchar[offset ++] = (char) (TargetPer >> 16);
            retchar[offset ++] = (char) (TargetPer & 0xffff);
            retchar[offset ++] = (char) (TargetPer >> 16);
            retchar[offset ++] = (char) (TargetPer & 0xffff);
            retchar[offset ++] = (char) (TargetPer >> 16);
            retchar[offset ++] = (char) (TargetPer & 0xffff);
            retchar[offset ++] = (char) (TargetPer >> 16);
            retchar[offset ++] = (char) (TargetPer & 0xffff);
            System.arraycopy(TACDenial, 0, retchar, offset, TACDenial.length);
            offset += TACDenial.length;
            System.arraycopy(TACOnline, 0, retchar, offset, TACOnline.length);
            offset += TACOnline.length;
            System.arraycopy(TACDefault, 0, retchar, offset, TACDefault.length);
            offset += TACDefault.length;
            System.arraycopy(AcquierId, 0, retchar, offset, AcquierId.length);
            offset += AcquierId.length;
            retchar[offset ++] = LenOfdDOL;
            System.arraycopy(dDOL, 0, retchar, offset, dDOL.length);
            offset += dDOL.length;
            retchar[offset ++] = LenOftDOL;
            System.arraycopy(tDOL, 0, retchar, offset, tDOL.length);
            offset += tDOL.length;
            System.arraycopy(Version, 0, retchar, offset, Version.length);
            offset += Version.length;
            retchar[offset ++] = RiskManDataLen;
            System.arraycopy(RiskManData, 0, retchar, offset, RiskManData.length);
            offset += RiskManData.length;
            System.arraycopy(tRFU, 0, retchar, offset, tRFU.length);
            offset += tRFU.length;
            return retchar;
        }
        
        public void setChar(char[] buff, int offset)
        {
            TargetPer = buff[offset++] << 16;
            TargetPer |= buff[offset++];
            MaxTargetPer = buff[offset++] << 16;
            MaxTargetPer |= buff[offset++];
            FloorLimit = buff[offset++] << 16;
            FloorLimit |= buff[offset++];
            Threshold = buff[offset++] << 16;
            Threshold |= buff[offset++];
            ECTransLimit = buff[offset++] << 16;
            ECTransLimit |= buff[offset++];
            QPBOCTransLimit = buff[offset++] << 16;
            QPBOCTransLimit |= buff[offset++];
            QPBOCFloorLimit = buff[offset++] << 16;
            QPBOCFloorLimit |= buff[offset++];
            QPBOCCVMLimit = buff[offset++] << 16;
            QPBOCCVMLimit |= buff[offset++];
            System.arraycopy(buff, offset, TACDenial, 0, TACDenial.length);
            offset += TACDenial.length;
            System.arraycopy(buff, offset, TACOnline, 0, TACOnline.length);
            offset += TACOnline.length;
            System.arraycopy(buff, offset, TACDefault, 0, TACDefault.length);
            offset += TACDefault.length;
            System.arraycopy(buff, offset, AcquierId, 0, AcquierId.length);
            offset += AcquierId.length;
            LenOfdDOL = buff[offset++];
            System.arraycopy(buff, offset, dDOL, 0, dDOL.length);
            offset += dDOL.length;
            LenOftDOL = buff[offset++];
            System.arraycopy(buff, offset, tDOL, 0, tDOL.length);
            offset += tDOL.length;
            System.arraycopy(buff, offset, Version, 0, Version.length);
            offset += Version.length;
            RiskManDataLen = buff[offset++];
            System.arraycopy(buff, offset, RiskManData, 0, RiskManData.length);
            offset += RiskManData.length;
            System.arraycopy(buff, offset, tRFU, 0, tRFU.length);
            offset += tRFU.length;
        }
        
        public int        TargetPer;              // 目标百分比数
        public int        MaxTargetPer;           // 最大目标百分比数
        public int        FloorLimit;                 // 最低限额
        public int        Threshold;              // 阀值
        public int        ECTransLimit;           // 终端电子现金交易限额
        public int        QPBOCTransLimit;        // 非接触交易限额
        public int        QPBOCFloorLimit;        // 非接触脱机最低限额
        public int        QPBOCCVMLimit;          // 执行CVM限额
        public char[]   TACDenial;    //5       // 终端行为代码(拒绝)
        public char[]   TACOnline;    //5       // 终端行为代码(联机)
        public char[]   TACDefault;   //5       // 终端行为代码(缺省)
        public char[]   AcquierId;    //6       // 收单行标志
        public char   LenOfdDOL;              // 终端缺省DDOL长度
        public char[]   dDOL;         //252     // 终端缺省DDOL
        public char   LenOftDOL;              // 终端缺省TDOL长度
        public char[]   tDOL;         //252     // 终端缺省TDOL
        public char[]   Version;      //2           // 应用版本
        public char   RiskManDataLen;         // 风险管理数据长度
        public char[]   RiskManData;  //8       // 风险管理数据
        public char[]   tRFU;         //2
    }

    private native int EmvSetAppInitData(EMV_APP_INIT_DATA[] pData);
    private native int EmvGetAppInitData(EMV_APP_INIT_DATA[] pData);
    
    public int Emv_set_app_init_data(EMV_APP_INIT_DATA[] pData)
    {
        return EmvSetAppInitData(pData);
    }
    public int Emv_get_app_init_data(EMV_APP_INIT_DATA[] pData)
    {
        return EmvGetAppInitData(pData);
    }
    
    
    public interface EMV_CALLBACK_FUNC
    {
        public int EmvSelectCandidateApplication();          // 持卡人选择应用，返回应用号
        public int EmvAccountTypeSelect();               // 帐户类型选择
        public int EmvGetTransactionAmount();            // 操作员输入交易金额，返回交易金额
        public int EmvGetCardholderPin(char[] arg1);             //持卡人输入密码，返回密码长度
        public int EmvShowPinVerifyResult(char arg1);     // 显示pin验证结果
        public int EmvProcessOnlinePin();                    // 联机pin验证
        public int EmvProcessPbocCertificate();              // 证书验证
        public int EmvProcessAdvice();                        // Advice处理
        public int EmvProcessOnline(char[] arg1, char[] arg2, int[] arg3, char[] arg4, int[] arg5,       // 联机交易处理
                                    char[] arg6, int[] arg7);
        public int EmvProcessIssuerRefer();              // 处理发卡行参考
        public int EmvSetTransactionData();              // 设置和AID相关的交易应用数据
        public int EmvEcAccountSelect();                 // 电子现金或借贷记帐户类型选择
    }

    private native int EmvSetCallbackFunction(EMV_CALLBACK_FUNC[] pFunc);
    
    public int Emv_set_callback_function(EMV_CALLBACK_FUNC[] pFunc)
    {
        return EmvSetCallbackFunction(pFunc);
    }
    
    private native int EmvReleaseCallback();
    
    public int Emv_release_callback()
    {
        return EmvReleaseCallback();
    }
    
    private native int EmvAlgorEnable(int smEn);
    
    public int Emv_algor_enable(int smEn)
    {
        return EmvAlgorEnable(smEn);
    }
    
 // MCK 配置结构
    public class TermMCK
    { // 按ICS中出现的先后顺序排列
        public TermMCK()
        {
            cTmType = 0;
            tTmCap = new char[3];
            tTmCapAd = new char[5];
            cSupPSESelect = 0;
            cSupAppConfirm = 0;
            cSupAppDispOrder = 0;
            cSupMulLang = 0;
            cSupIssCertCheck = 0;
            cSupDDOLFlg = 0;
            
            cSupBypassPIN = 0;
            cSupFlrLmtCheck = 0;
            cSupRndOnlineSlt = 0;
            cSupVeloCheck = 0;
            cSupTransLog = 0;
            
            cSupExcptCheck = 0;
            cTmRmCheckFlg = 0;
            cSupTmActionCode = 0;
            cSupForceOnline = 0;
            cSupForceAccept = 0;
            
            cSupAdvice = 0;
            cSupIssVoiceRef = 0;
            cSupCardVoiceRef = 0;
            cSupBatchCollect = 0;
            cSupOnlineCollect = 0;
            
            cSupTDOLFlg = 0;
            cPOSEntryMode = 0;
            tHashVal = new char[20];
        }
        public void clear()
        {
            cTmType = 0;
            Arrays.fill(tTmCap, (char) 0x00);
            Arrays.fill(tTmCapAd, (char) 0x00);
            cSupPSESelect = 0;
            cSupAppConfirm = 0;
            cSupAppDispOrder = 0;
            cSupMulLang = 0;
            cSupIssCertCheck = 0;
            cSupDDOLFlg = 0;
            
            cSupBypassPIN = 0;
            cSupFlrLmtCheck = 0;
            cSupRndOnlineSlt = 0;
            cSupVeloCheck = 0;
            cSupTransLog = 0;
            
            cSupExcptCheck = 0;
            cTmRmCheckFlg = 0;
            cSupTmActionCode = 0;
            cSupForceOnline = 0;
            cSupForceAccept = 0;
            
            cSupAdvice = 0;
            cSupIssVoiceRef = 0;
            cSupCardVoiceRef = 0;
            cSupBatchCollect = 0;
            cSupOnlineCollect = 0;
            
            cSupTDOLFlg = 0;
            cPOSEntryMode = 0;
            Arrays.fill(tHashVal, (char) 0x00);
        }
        public int sizeof()
        {
            int len = 0;
            len += 1;
            len += tTmCap.length;
            len += tTmCapAd.length;
            len += 23;
            len += tHashVal.length;
            return len;
        }
        public char[] getChar()
        {
            char[] retchar = new char[this.sizeof()];
            int offset = 0;
            retchar[offset++] = cTmType;
            System.arraycopy(tTmCap, 0, retchar, offset, tTmCap.length);
            offset += tTmCap.length;
            System.arraycopy(tTmCapAd, 0, retchar, offset, tTmCapAd.length);
            offset += tTmCapAd.length;
            retchar[offset++] = cSupPSESelect;
            
            retchar[offset++] = cSupAppConfirm;
            retchar[offset++] = cSupAppDispOrder;
            retchar[offset++] = cSupMulLang;
            retchar[offset++] = cSupIssCertCheck;
            retchar[offset++] = cSupDDOLFlg;
            
            retchar[offset++] = cSupBypassPIN;
            retchar[offset++] = cSupFlrLmtCheck;
            retchar[offset++] = cSupRndOnlineSlt;
            retchar[offset++] = cSupVeloCheck;
            retchar[offset++] = cSupTransLog;
            
            retchar[offset++] = cSupExcptCheck;
            retchar[offset++] = cTmRmCheckFlg;
            retchar[offset++] = cSupTmActionCode;
            retchar[offset++] = cSupForceOnline;
            retchar[offset++] = cSupForceAccept;
            
            retchar[offset++] = cSupAdvice;
            retchar[offset++] = cSupIssVoiceRef;
            retchar[offset++] = cSupCardVoiceRef;
            retchar[offset++] = cSupBatchCollect;
            retchar[offset++] = cSupOnlineCollect;
            
            retchar[offset++] = cSupTDOLFlg;
            retchar[offset++] = cPOSEntryMode;
            System.arraycopy(tHashVal, 0, retchar, offset, tHashVal.length);
            offset += tHashVal.length;
            return retchar;
            
        }
        
        public void setChar(char[] buff, int offset)
        {
            cTmType = buff[offset ++];
            System.arraycopy(buff, offset, tTmCap, 0, tTmCap.length);
            offset += tTmCap.length;
            System.arraycopy(buff, offset, tTmCapAd, 0, tTmCapAd.length);
            offset += tTmCapAd.length;
            cSupPSESelect = buff[offset ++];
            
            cSupAppConfirm = buff[offset ++];
            cSupAppDispOrder = buff[offset ++];
            cSupMulLang = buff[offset ++];
            cSupIssCertCheck = buff[offset ++];
            cSupDDOLFlg = buff[offset ++];
            
            cSupBypassPIN = buff[offset ++];
            cSupFlrLmtCheck = buff[offset ++];
            cSupRndOnlineSlt = buff[offset ++];
            cSupVeloCheck = buff[offset ++];
            cSupTransLog = buff[offset ++];
            
            cSupExcptCheck = buff[offset ++];
            cTmRmCheckFlg = buff[offset ++];
            cSupTmActionCode = buff[offset ++];
            cSupForceOnline = buff[offset ++];
            cSupForceAccept = buff[offset ++];
            
            cSupAdvice = buff[offset ++];
            cSupIssVoiceRef = buff[offset ++];
            cSupCardVoiceRef = buff[offset ++];
            cSupBatchCollect = buff[offset ++];
            cSupOnlineCollect = buff[offset ++];
            
            cSupTDOLFlg = buff[offset ++];
            cPOSEntryMode = buff[offset ++];
            System.arraycopy(buff, offset, tTmCapAd, 0, tTmCapAd.length);
            offset += tTmCapAd.length;
            
        }
        public char   cTmType;            // 终端类型     (默认为0x22)
        public char[]   tTmCap;    //3      // 终端性能     (默认为 0xE0,0xF8,0xC8)
        public char[]   tTmCapAd;  //5      // 附加终端性能 (默认为 0x6F,0x00,0xF0,0xF0,0x01)
        public char   cSupPSESelect;      // PSE选择方式  (默认为 支持)

        public char   cSupAppConfirm;     // 是否支持持卡人确认及选择应用 (默认为 支持)
        public char   cSupAppDispOrder;   // 支持按指定顺序显示候选应用   (默认为 支持)
        public char   cSupMulLang;        // 支持多语言    (默认为 不支持)
        public char   cSupIssCertCheck ;  // IssCert 检查 (默认为 支持)
        public char   cSupDDOLFlg ;       // 支持默认DDOL (默认为 支持)

        public char   cSupBypassPIN;      // Bypass PIN, 可跳过密码 (默认为 支持)
        public char   cSupFlrLmtCheck ;   // 最低限额检查 (默认为 支持)
        public char   cSupRndOnlineSlt;   // 随机联机选择 (默认为 支持)
        public char   cSupVeloCheck;      // 频度检查     (默认为 支持)
        public char   cSupTransLog;       // 交易流水     (默认为 支持)

        public char   cSupExcptCheck ;    // 异常文件检查 (默认为 支持)
        public char   cTmRmCheckFlg ;     // 终端风险管理的执行是否基于卡片AIP  (默认为 是)
        public char   cSupTmActionCode;   // 是否支持终端行为代码 (默认为 支持)
        public char   cSupForceOnline;    // 交易强制联机能力 (默认为 支持)
        public char   cSupForceAccept;    // 交易强制接受能力 (默认为 支持)

        public char   cSupAdvice;         // 终端是否支持通知 (默认为 支持)
        public char   cSupIssVoiceRef;    // 支持发卡行发起的参考 (默认为 支持)
        public char   cSupCardVoiceRef;   // 支持卡片发起的参考 (默认为 支持)
        public char   cSupBatchCollect;   // 支持批数据采集  (默认为 支持)
        public char   cSupOnlineCollect;  // 支持联机数据采集(默认为 不支持)

        public char   cSupTDOLFlg ;       // 支持默认TDOL     (默认为 支持)
        public char   cPOSEntryMode;      // POS　Entry Code  (默认为0x25)
        public char[]   tHashVal;  //20     // 与各配置对应的hash值
    }  // 1-> 支持

    private native int EmvSetMck(TermMCK[] pMCK); // 配置终端MCK
    private native int EmvGetMck(TermMCK[] pMCK); // 获取终端当前的MCK
    
    public int Emv_set_mck(TermMCK[] pMCK) // 配置终端MCK
    {
        return EmvSetMck(pMCK);
    }
    public int Emv_get_mck(TermMCK[] pMCK) // 获取终端当前的MCK
    {
        return EmvGetMck(pMCK);
    }
    
    private native int EmvInitBinlist(int type);                             // 初始化BIN列表，删除原有的所有BIN信息
    private native int EmvSetBinlist(int type, int Num, char[][] pBinList);   // 设置BIN列表，一次性输入所有的BIN信息
    private native int EmvCheckBin(int type, char[] pBin);
    
    public int Emv_init_binlist(int type)                             // 初始化BIN列表，删除原有的所有BIN信息
    {
        return EmvInitBinlist(type);
    }
    public int Emv_set_binlist(int type, int Num, char[][] pBinList)   // 设置BIN列表，一次性输入所有的BIN信息
    {
        return EmvSetBinlist(type, Num, pBinList);
    }
    public int Emv_check_bin(int type, char[] pBin)
    {
        return EmvCheckBin(type, pBin);
    }
    
    public class DAidList
    {
        public DAidList()
        {
            cLen = 0;
            tAID = new char[16];
            SelFlag = 0;
            tRFU = new char[2];
        }
        public void clear()
        {
            cLen = 0;
            SelFlag = 0;
            Arrays.fill(tAID, (char) 0x00);
        }
        public int sizeof()
        {
            return (2 + tAID.length + tRFU.length);
        }
        public char   cLen;            // AID名称的长度
        public char[]   tAID;   //16     // AID名称
        public char   SelFlag;         // 选择标志(1 部分匹配  0 全匹配)
        public char[]   tRFU;   //2
    }

    private native void EmvInitAidlist();                               // 初始化AID列表，删除原有的所有AID信息
    private native int EmvSetAidlist(int Num, DAidList[] pAidList);   // 设置AID列表，一次性输入所有的AID信息
    private native int EmvAddAidItem(char AidLen, char[] pAid, char SelFlag); // 增加一个AID信息
    private native int EmvGetAidNum();                          // 返回当前保存的AID数目
    private native int EmvDelAidItem(char AidLen, char[] pAid);        // 删除一个AID
    private native int EmvGetAidByIndex(int index, DAidList[] pAidList); // 获取第index个AID信息
    private native int EmvCheckAid(char AidLen, char[] pAid);           // 检测该AID是否存在
    
    
    public void Emv_init_aidlist()                              // 初始化AID列表，删除原有的所有AID信息
    {
        EmvInitAidlist();
    }
    public int Emv_set_aidlist(int Num, DAidList[] pAidList)   // 设置AID列表，一次性输入所有的AID信息
    {
        return EmvSetAidlist(Num, pAidList);
    }
    public int Emv_add_aid_item(char AidLen, char[] pAid, char SelFlag) // 增加一个AID信息
    {
        return EmvAddAidItem(AidLen, pAid, SelFlag);
    }
    public int Emv_get_aid_num()                          // 返回当前保存的AID数目
    {
        return EmvGetAidNum();
    }
    public int Emv_del_aid_item(char AidLen, char[] pAid)        // 删除一个AID
    {
        return EmvDelAidItem(AidLen, pAid);
    }
    public int Emv_get_aid_by_index(int index, DAidList[] pAidList) // 获取第index个AID信息
    {
        return EmvGetAidByIndex(index, pAidList);
    }
    public int Emv_check_aid(char AidLen, char[] pAid)           // 检测该AID是否存在
    {
        return EmvCheckAid(AidLen, pAid);
    }
    
    public class PKFILESTRU
    {
        public PKFILESTRU()
        {
            cRid = new char[5];
            cIndex = 0;
            cModLen = 0;
            cMod = new char[248];
            cExpLen = 0;
            cExp = new char[3];
            cExpDate = new char[4];
            cHashFlg = 0;
            cHash = new char[32];
        }
        public void clear()
        {
            Arrays.fill(cRid, (char) 0x00);
            cIndex = 0;
            cModLen = 0;
            Arrays.fill(cMod, (char) 0x00);
            cExpLen = 0;
            Arrays.fill(cExp, (char) 0x00);
            Arrays.fill(cExpDate, (char) 0x00);
            cHashFlg = 0;
            Arrays.fill(cHash, (char) 0x00);
        }
        public int sizeof()
        {
            int len = 0;
            len += cRid.length;
            len += 2;
            len += cMod.length;
            len += 1;
            len += cExp.length;
            len += cExpDate.length;
            len += 1;
            len += cHash.length;
            return len;
        }
        public char[] getChar()
        {
            char[] retchar = new char[this.sizeof()];
            int offset = 0;
            System.arraycopy(cRid, 0, retchar, offset, cRid.length);
            offset += cRid.length;
            retchar[offset ++] = cIndex;
            retchar[offset ++] = cModLen;
            System.arraycopy(cMod, 0, retchar, offset, cMod.length);
            offset += cMod.length;
            retchar[offset ++] = cExpLen;
            System.arraycopy(cExp, 0, retchar, offset, cExp.length);
            offset += cExp.length;
            System.arraycopy(cExpDate, 0, retchar, offset, cExpDate.length);
            offset += cExpDate.length;
            retchar[offset ++] = cHashFlg;
            System.arraycopy(cHash, 0, retchar, offset, cHash.length);
            offset += cHash.length;
            return retchar;
        }
        public void setChar(char[] buff, int offset)
        {
            System.arraycopy(buff, offset, cRid, 0, cRid.length);
            offset += cRid.length;
            cIndex = buff[offset ++];
            cModLen = buff[offset ++];
            System.arraycopy(buff, offset, cMod, 0, cMod.length);
            offset += cMod.length;
            cExpLen = buff[offset ++];
            System.arraycopy(buff, offset, cExp, 0, cExp.length);
            offset += cExp.length;
            System.arraycopy(buff, offset, cExpDate, 0, cExpDate.length);
            offset += cExpDate.length;
            cHashFlg = buff[offset ++];
            System.arraycopy(buff, offset, cHash, 0, cHash.length);
            offset += cHash.length;
        }
        public char[]   cRid;  //5        // RID
        public char   cIndex;         // 公钥索引
        public char   cModLen;        // 公钥模的长度
        public char[]   cMod;  //248      // 公钥模
        public char   cExpLen;        // 公钥指数的长度
        public char[]   cExp;  //3        // 公钥指数
        public char[]   cExpDate;  //4    // 公钥失效期, YYYYMMDD
        public char   cHashFlg;       // 公钥校验和是否存在
        public char[]   cHash; //32      // 公钥校验和 - 用于定期检查, 可不赋值
    }

    private native void EmvInitCapklist();                               // 初始化CAPK列表，删除原有的所有CAPK
    private native int EmvDelCapk(char[] pRid, char cIndex);            // 删除一个CAPK
    private native int EmvAddCapkItem(PKFILESTRU[]  pCAPKStru);      // 增加一个CAPK
    private native int EmvChangeCapkExpdate(char[] pRid, char cIndex, char[] pExpDate); // 更改指定CAPK的过期日期
    private native int EmvGetCapkNum();                         // 获取CAPK总数目
    private native int EmvGetCapkItem(char[] pRid, char cIndex, PKFILESTRU[] cpkeystru);    // 根据RID和Index获取CAPK
    private native int EmvGetCapkByIndex(char cNo, PKFILESTRU[] pCAPKeyInfo);          // 获取第cNo个CAPK

    public void Emv_init_capklist()                               // 初始化CAPK列表，删除原有的所有CAPK
    {
        EmvInitCapklist(); 
    }
    public int Emv_del_capk(char[] pRid, char cIndex)            // 删除一个CAPK
    {
        return EmvDelCapk(pRid, cIndex);
    }
    public int Emv_add_capk_item(PKFILESTRU[]  pCAPKStru)      // 增加一个CAPK
    {
        return EmvAddCapkItem(pCAPKStru);
    }
    public int Emv_change_capk_expdate(char[] pRid, char cIndex, char[] pExpDate) // 更改指定CAPK的过期日期
    {
        return EmvChangeCapkExpdate(pRid, cIndex, pExpDate);
    }
    public int Emv_get_capk_num()                         // 获取CAPK总数目
    {
        return EmvGetCapkNum();
    }
    public int Emv_get_capk_item(char[] pRid, char cIndex, PKFILESTRU[] cpkeystru)    // 根据RID和Index获取CAPK
    {
        return EmvGetCapkItem(pRid, cIndex, cpkeystru);
    }
    public int Emv_get_capk_by_index(char cNo, PKFILESTRU[] pCAPKeyInfo)          // 获取第cNo个CAPK
    {
        return EmvGetCapkByIndex(cNo, pCAPKeyInfo);
    }
    
    public class ExceptFile
    {
        public ExceptFile()
        {
            PANLen = 0;
            Pan = new char[10];
            PANSn = 0;
        }
        public void clear()
        {
            PANLen = 0;
            Arrays.fill(Pan, (char) 0x00);
            PANSn = 0;
        }
        
        public char PANLen;
        public char[] Pan; //10
        public char PANSn;
    };

    private native void EmvInitExceptFiles();   // 清除所有的黑名单
    private native int EmvAddExceptFileItem(char PANLen, char[] Pan, char PANSn);    // 增加一个黑名单
    private native int EmvDelExceptFileItem(char PANLen, char[] Pan, char PANSn);        // 删除一个黑名单
    private native int EmvGetExceptFileNum();  // 获取黑名单个数
    private native int EmvCheckExceptFile(char PANLen, char[] Pan, char PANSn);   // 检测该Pan是否处于黑名单中
    private native int EmvSetExceptFileList(int Num, ExceptFile[] pExceptFile);     // 一次性设置所有的黑名单
    private native int EmvGetExceptFileList(int Num, ExceptFile[] pExceptFile);     // 一次性获取多个黑名单
    
    public void Emv_init_except_files()   // 清除所有的黑名单
    {
        EmvInitExceptFiles();
    }
    public int Emv_add_except_file_item(char PANLen, char[] Pan, char PANSn)    // 增加一个黑名单
    {
        return EmvAddExceptFileItem(PANLen, Pan, PANSn);
    }
    public int Emv_del_except_file_item(char PANLen, char[] Pan, char PANSn)        // 删除一个黑名单
    {
        return EmvDelExceptFileItem(PANLen, Pan, PANSn);
    }
    public int Emv_get_except_file_num()  // 获取黑名单个数
    {
        return EmvGetExceptFileNum();
    }
    public int Emv_check_except_file(char PANLen, char[] Pan, char PANSn)   // 检测该Pan是否处于黑名单中
    {
        return EmvCheckExceptFile(PANLen, Pan, PANSn);
    }
    public int Emv_set_except_file_list(int Num, ExceptFile[] pExceptFile)     // 一次性设置所有的黑名单
    {
        return EmvSetExceptFileList(Num, pExceptFile);
    }
    public int Emv_get_except_file_list(int Num, ExceptFile[] pExceptFile)     // 一次性获取多个黑名单
    {
        return EmvGetExceptFileList(Num, pExceptFile);
    }
    
    
    public class IssCRL
    {
        public IssCRL()
        {
            cIndex = 0;
            cRid = new char[5];
            cCertSn = new char[3];
            tRFU = new char[3];
        }
        public void clear()
        {
            cIndex = 0;
            Arrays.fill(cRid, (char) 0x00);
            Arrays.fill(cCertSn, (char) 0x00);
            Arrays.fill(tRFU, (char) 0x00);
        }
        public int sizeof()
        {
            int len;
            len = 1;
            len += cRid.length;
            len += cCertSn.length;
            len += tRFU.length;
            return len;
        }
        public char[] getChar()
        {
            char[] retchar = new char[this.sizeof()];
            int offset = 0;
            retchar[offset ++] = cIndex;
            System.arraycopy(cRid, 0, retchar, offset, cRid.length);
            offset += cRid.length;
            System.arraycopy(cCertSn, 0, retchar, offset, cCertSn.length);
            offset += cCertSn.length;
            System.arraycopy(tRFU, 0, retchar, offset, tRFU.length);
            offset += tRFU.length;
            return retchar;
        }
        public void setChar(char[] buff, int offset)
        {
            cIndex = buff[offset++];
            System.arraycopy(buff, offset, cRid, 0, cRid.length);
            offset += cRid.length;
            System.arraycopy(buff, offset, cCertSn, 0, cCertSn.length);
            offset += cCertSn.length;
            System.arraycopy(buff, offset, tRFU, 0, tRFU.length);
            offset += tRFU.length;
        }
        public char   cIndex;                 // 公钥索引
        public char[]   cRid;       //5            // RID
        public char[]   cCertSn;     //3        // 证书序列号
        public char[]   tRFU;       //3         // RFU,将结构字节数填充为4的整数倍
    }

    private native void EmvInitIsscrl();     // 清除所有的发卡行回收证书列表
    private native int EmvAddIsscrlItem(char cIndex, char[] pRid, char[] pCertSn); // 增加一个回收证书
    private native int EmvDelIsscrlItem(char cIndex, char[] pRid, char[] pCertSn); // 删除一个回收证书
    private native int EmvGetIsscrlNum();   // 获取回收证书个数
    private native int EmvCheckIsscrl(char cIndex, char[] pRid, char[] pCertSn); // 检测该公钥是否已被回收
    private native int EmvSetIsscrlList(int Num, IssCRL[] pCert);    // 一次性设置所有的回收证书
    private native int EmvGetIsscrlList(int Num, IssCRL[] pCert);    // 一次性获取多次回收证书
    
    
    public void Emv_init_isscrl()     // 清除所有的发卡行回收证书列表
    {
        EmvInitIsscrl();
    }
    public int Emv_add_isscrl_item(char cIndex, char[] pRid, char[] pCertSn) // 增加一个回收证书
    {
        return EmvAddIsscrlItem(cIndex, pRid, pCertSn);
    }
    public int Emv_del_isscrl_item(char cIndex, char[] pRid, char[] pCertSn) // 删除一个回收证书
    {
        return EmvDelIsscrlItem(cIndex, pRid, pCertSn);
    }
    public int Emv_get_isscrl_num()   // 获取回收证书个数
    {
        return EmvGetIsscrlNum();
    }
    public int Emv_check_isscrl(char cIndex, char[] pRid, char[] pCertSn) // 检测该公钥是否已被回收
    {
        return EmvCheckIsscrl(cIndex, pRid, pCertSn);
    }
    public int Emv_set_isscrl_list(int Num, IssCRL[] pCert)    // 一次性设置所有的回收证书
    {
        return EmvSetIsscrlList(Num, pCert);
    }
    public int Emv_get_isscrl_list(int Num, IssCRL[] pCert)    // 一次性获取多次回收证书
    {
        return EmvGetIsscrlList(Num, pCert);
    }
    
 // 交易记录操作
    public class TransLog
    {
        public TransLog()
        {
            PanLen = 0;
            Pan = new char[10];
            PANSn = 0;
            TransAmount = 0;
            TransTime = new char[6];
            tRFU = new char[2];
        }
        public void clear()
        {
            PanLen = 0;
            Arrays.fill(Pan, (char) 0x00);
            PANSn = 0;
            TransAmount = 0;
            Arrays.fill(TransTime, (char) 0x00);
        }
        public char    PanLen;            // Pan号长度
        public char[]    Pan;    //10           // 卡Pan号
        public char    PANSn;             // Pan序列号
        public int     TransAmount;       // 交易金额
        public char[]    TransTime;  //6     // 交易时间YYMMDDHHMMSS
        public char[]    tRFU;    //2       // 预留
    }

    private native void EmvInitTranslogs();
    private native int EmvAddTranslogItem(TransLog[] pLog);
    private native int EmvGetTranslogs(int LogNum, TransLog[] pLog);
    private native int EmvGetTranslogItem(TransLog[] pLog);
    private native int EmvGetTranslogsNum();
    
    public void Emv_init_translogs()
    {
        EmvInitTranslogs();
    }
    public int Emv_add_translog_item(TransLog[] pLog)
    {
        return EmvAddTranslogItem(pLog);
    }
    public int Emv_get_translogs(int LogNum, TransLog[] pLog)
    {
        return EmvGetTranslogs(LogNum, pLog);
    }
    public int Emv_get_translog_item(TransLog[] pLog)
    {
        return EmvGetTranslogItem(pLog);
    }
    public int Emv_get_translogs_num()
    {
        return EmvGetTranslogsNum();
    }

    private native void EmvInitAllDataElements();      // 初始化所有的数据元，包含终端数据元和IC卡数据元
    private native void EmvInitIccDataElements();  // 初始化所有的IC卡数据元
    private native int EmvSetDataElement(int Tag, int pLen, char[] pVal);    // 设置一个数据元
    private native int EmvGetDataElement(int Tag, int[] pLen, char[] pVal);   // 获取一个数据元
    private native int  EmvCheckDataElement(int Tag);    // 检测该数据元是否已设置
    private native int EmvDelDataElement(int Tag);   // 删除一个数据元
    
    public void Emv_init_all_data_elements()      // 初始化所有的数据元，包含终端数据元和IC卡数据元
    {
        EmvInitAllDataElements();
    }
    public void Emv_init_icc_data_elements()  // 初始化所有的IC卡数据元
    {
        EmvInitIccDataElements();
    }
    public int Emv_set_data_element(int Tag, int pLen, char[] pVal)    // 设置一个数据元
    {
        return EmvSetDataElement(Tag, pLen, pVal);
    }
    public int Emv_get_data_element(int Tag, int[] pLen, char[] pVal)   // 获取一个数据元
    {
        return EmvGetDataElement(Tag, pLen, pVal);
    }
    public int  Emv_check_data_element(int Tag)    // 检测该数据元是否已设置
    {
        return EmvCheckDataElement(Tag);
    }
    public int Emv_del_data_element(int Tag)   // 删除一个数据元
    {
        return EmvDelDataElement(Tag);
    }
    
    public class EMV_CANDAPP_LIST
    {
        public EMV_CANDAPP_LIST()
        {
            tCandAppName = new char[33];
            cFlgAPID = 0;
            cAPID = 0;
            tRFU = 0;
        }
        
        public void clear()
        {
            Arrays.fill(tCandAppName, (char) 0x00);
            cFlgAPID = 0;
            cAPID = 0;
        }
        public char[]   tCandAppName;    //33
        public char   cFlgAPID;
        public char   cAPID;
        public char   tRFU;
    }

    /* 定义AID列表的结构 */
    public class DCandList
    {
        public DCandList()
        {
            tAID = new char[16];
            cLenAID = 0;
            tAppLabel = new char[16];
            cLenLabel = 0;
            tAPN = new char[16];
            cLenAPN = 0;
            cAPID = 0;
            cFlgAPID = 0;
            sLangPref = new char[8];
            cLenLangPref = 0;
            cIssCTIndex = 0;
            cFlgIssCTIndex = 0;
            cFlgPreferNameFlg = 0;
            cLenPDOL = 0;
            tPDOL = new char[256];
        }
        
        public void clear()
        {
            Arrays.fill(tAID, (char) 0x00);
            cLenAID = 0;
            Arrays.fill(tAppLabel, (char) 0x00);
            cLenLabel = 0;
            Arrays.fill(tAPN, (char) 0x00);
            cLenAPN = 0;
            cAPID = 0;
            cFlgAPID = 0;
            Arrays.fill(sLangPref, (char) 0x00);
            cLenLangPref = 0;
            cIssCTIndex = 0;
            cFlgIssCTIndex = 0;
            cFlgPreferNameFlg = 0;
            cLenPDOL = 0;
            Arrays.fill(tPDOL, (char) 0x00);
        }
        public char[]   tAID;       //16        // AID
        public char   cLenAID;
        public char[]   tAppLabel;    //16      // 应用标签
        public char   cLenLabel;
        public char[]   tAPN;     //16         // 应用首选名
        public char   cLenAPN;
        public char   cAPID;                  // 应用优先权标识符
        public char   cFlgAPID;               // 应用优先权标识符标志
        public char[]   sLangPref;  //8         // 首选语言
        public char   cLenLangPref;
        public char   cIssCTIndex;            // 发卡行代码表索引
        public char   cFlgIssCTIndex;
        public char   cFlgPreferNameFlg;      // 是否使用应用主选名
        public char   cLenPDOL;
        public char[]   tPDOL;   //256
    }

    private native void EmvGetAllCandAppInfo(int[] CandAppNum, EMV_CANDAPP_LIST[] pCandApp);
    private native int EmvGetCandApp(int cIndex, DCandList[] pCandList);
    
    public void Emv_Get_All_CandAppInfo(int[] CandAppNum, EMV_CANDAPP_LIST[] pCandApp)
    {
        EmvGetAllCandAppInfo(CandAppNum, pCandApp);
    }
    public int Emv_Get_CandApp(int cIndex, DCandList[] pCandList)
    {
        return EmvGetCandApp(cIndex, pCandList);
    }

 // EMV交易接口
    private native int EmvCardslotInit(int CardSlot);
    private native void EmvSetPseType(int nFlag);
    private native int EmvGetPseType();
    private native int EmvApplicationSelect(int TransNo);
    private native int EmvReadAppData();
    private native int EmvOfflineDataAuth();
    private native int EmvCardholderVerify();
    private native void EmvProcessRestriction();
    private native int EmvTermRiskManage();
    private native int EmvCompleteTransaction();
    
    
    public int Emv_cardslot_init(int CardSlot)
    {
        return EmvCardslotInit(CardSlot);
    }
    public void Emv_set_pse_type(int nFlag)
    {
        EmvSetPseType(nFlag);
    }
    public int Emv_get_pse_type()
    {
        return EmvGetPseType();
    }
    public int Emv_application_select(int TransNo)
    {
        return EmvApplicationSelect(TransNo);
    }
    public int Emv_read_app_data()
    {
        return EmvReadAppData();
    }
    public int Emv_offline_data_auth()
    {
        return EmvOfflineDataAuth();
    }
    public int Emv_cardholder_verify()
    {
        return EmvCardholderVerify();
    }
    public void Emv_process_restriction()
    {
        EmvProcessRestriction();
    }
    public int Emv_term_risk_manage()
    {
        return EmvTermRiskManage();
    }
    public int Emv_complete_transaction()
    {
        return EmvCompleteTransaction();
    }
    
    private native int EmvApplicationSelectReadLog(int TransNo);
    private native int ReadLogRecord(int RecordNo);
    private native int GetLogItem(char[] Tag, char TagLen, char[] Value, int[] ValueLen);
    private native int ReadLoadLogRecord(int RecordNo);
    private native int GetLoadLogItem(char[] Tag, char TagLen, char[] Value, int[] ValueLen);
    private native int GetLoadLogHead(char[] Value);
    private native int ReadLoadLogAll(char[] pLoadLog, int[] pLogLen);
    
    
    public int Emv_application_select_read_log(int TransNo)
    {
        return EmvApplicationSelectReadLog(TransNo);
    }
    public int Read_log_record(int RecordNo)
    {
        return ReadLogRecord(RecordNo);
    }
    public int Get_log_item(char[] Tag, char TagLen, char[] Value, int[] ValueLen)
    {
        return GetLogItem(Tag, TagLen, Value, ValueLen);
    }
    public int Read_load_log_record(int RecordNo)
    {
        return ReadLoadLogRecord(RecordNo);
    }
    public int Get_load_log_item(char[] Tag, char TagLen, char[] Value, int[] ValueLen)
    {
        return GetLoadLogItem(Tag, TagLen, Value, ValueLen);
    }
    public int Get_load_log_head(char[] Value)
    {
        return GetLoadLogHead(Value);
    }
    public int Read_load_log_all(char[] pLoadLog, int[] pLogLen)
    {
        return ReadLoadLogAll(pLoadLog, pLogLen);
    }
    
    
    private native int EmvCheckForceAccept();
    private native int EmvGetScriptResult(char[] Result, int[] RetLen);
    private native int EmvCheckPrintSignature();
    private native int EmvPreonlineTransaction();
    private native int EmvOnlinebackTransaction(char[] pRspCode,char[] pAuthCode, int[] pAuthCodeLen,
            char[] pIAuthData, int[] pIAuthDataLen, char[] pScript1, int[] pScriptLen1, char[] pScript2, int[] pScriptLen2);

    public int Emv_check_force_accept()
    {
        return EmvCheckForceAccept();
    }
    public int Emv_get_script_result(char[] Result, int[] RetLen)
    {
        return EmvGetScriptResult(Result, RetLen);
    }
    public int Emv_check_print_signature()
    {
        return EmvCheckPrintSignature();
    }
    public int Emv_preonline_transaction()
    {
        return EmvPreonlineTransaction();
    }
    public int Emv_onlineback_transaction(char[] pRspCode,char[] pAuthCode, int[] pAuthCodeLen, char[] pIAuthData, int[] pIAuthDataLen, char[] pScript1, int[] pScriptLen1, char[] pScript2, int[] pScriptLen2)
    {
        return EmvOnlinebackTransaction(pRspCode, pAuthCode, pAuthCodeLen, pIAuthData, pIAuthDataLen, pScript1, pScriptLen1, pScript2, pScriptLen2);
    }
    
    
    //qPBOC交易接口
    private native int QpbocOfflineDataAuth();
    private native int QpbocTermRiskManage();
    private native int QpbocCompleteTransaction();
    private native int QpbocTransPreprocess();
    private native int QpbocCheckExceptFile(char PANLen, char[] Pan);  // 检测该Pan是否处于黑名单中

    public int QPBOC_offline_data_auth()
    {
        return QpbocOfflineDataAuth();
    }
    public int QPBOC_term_risk_manage()
    {
        return QpbocTermRiskManage();
    }
    public int QPBOC_complete_transaction()
    {
        return QpbocCompleteTransaction();
    }
    public int QPBOC_trans_preprocess()
    {
        return QpbocTransPreprocess();
    }
    public int QPBOC_check_except_file(char PANLen, char[] Pan)  // 检测该Pan是否处于黑名单中
    {
        return QpbocCheckExceptFile(PANLen, Pan);
    }
    
    //蒋工要的两个接口
    public native int EmvProcessTransOnline();
    public native int EmvCompleteTransJG();
    
    public int emv_process_transaction_online()
    {
        return EmvProcessTransOnline();
    }
    public int emv_complete_transaction_jg()
    {
        return EmvCompleteTransJG();
    }
    
    //卡片指令
    private native int EmvIccGetData(int p1, int p2, char[] DataOut, int[] OutLen);
    
    public int Emv_icc_get_data(int p1, int p2, char[] DataOut, int[] OutLen)
    {
        return EmvIccGetData(p1, p2, DataOut, OutLen);
    }
    
    public interface EMV_ICAdapterStruDef
    {
        public int  glICAdapterSelectCard(int lIndex);
        public int  glICAdapterCardIn(int arg1);
        public int  glICAdapterPowerUp(int arg1, int[] arg2, char[] arg3);
        public int  glICAdapterPowerDown(int arg1);
        public int  glICAdapterExchangeAPDU(int arg1, int arg2, char[] arg3, int[] arg4, char[] arg5);
    }
    
    private native int EmvICAdapterSet(EMV_ICAdapterStruDef[] tEMVICAdapter);
    
    public int Emv_ICAdapterSet(EMV_ICAdapterStruDef[] tEMVICAdapter)
    {
        return  EmvICAdapterSet(tEMVICAdapter);
    }
    
    public interface EMV_DebugStru
    {
        public int  EmvDebugOut(char[] msg);
    }
    private native int EmvDebugSet(EMV_DebugStru[] tEMVDebug);
    private native int EmvDebugCtrl(int flag);
    private native int EmvDebugCtrl(boolean flag);
    
    public int Emv_DebugSet(EMV_DebugStru[] tEMVDebug)
    {
        return  EmvDebugSet(tEMVDebug);
    }
    
    public int Emv_DebugCtrl(int flag)
    {
        return  EmvDebugCtrl(flag);
    }
    
    public int Emv_DebugCtrl(boolean flag)
    {
        return  EmvDebugCtrl(flag);
    }
    
    private native void EmvGetErrCode(int[] errcode);
    
    public void Emv_get_err_code(int[] errcode)
    {
        EmvGetErrCode(errcode);
    }
}
